#ifndef SPIKE_RECOVERY_TEST_DEMO_H
#define SPIKE_RECOVERY_TEST_DEMO_H

#include <QDoubleSpinBox>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QObject>
#include <QProgressBar>
#include <QPushButton>
#include <QSpinBox>
#include <QTextEdit>
#include <QTimer>
#include <QVBoxLayout>
#include <QWidget>

// 引用项目中的ModbusHelper
#include "../../code/modbus/ModbusHelper.h"

/**
 * @brief 加标回收测试Demo类
 *
 * 实现13步加标回收测试流程:
 * 1. 006FH 设置成 0x0001 (加标回收)
 * 2. 0064H 设置成 0x01 (选择动态加标)
 * 3. 0099H 设置成 0x01 (启动流程)
 * 4. 读取0303H等待准备完成
 * 5. 向0302H写入0x0001开始第一次分析
 * 6. 向0300H 0301H写入第一次浓度值
 * 7. 向0302H写入0x0000分析完成
 * 8. 读取0303H等待准备完成
 * 9. 向0302H写入0x0001开始第二次分析
 * 10. 向0300H 0301H写入第二次浓度值
 * 11. 向0302H写入0x0000分析完成
 * 12. 读取0305H 0306H获取加标回收率
 * 13. 流程结束
 */
class SpikeRecoveryTestDemo : public QWidget
{
    Q_OBJECT

public:
    explicit SpikeRecoveryTestDemo(QWidget* parent = nullptr);
    ~SpikeRecoveryTestDemo();

private slots:
    // 连接相关
    void onConnectClicked();
    void onDisconnectClicked();

    // 测试流程相关
    void onStartTestClicked();
    void onStopTestClicked();
    void onResetClicked();

    // 步骤执行相关
    void executeNextStep();
    void onStepCompleted();
    void onStepFailed(const QString& error);

    // Modbus通信相关
    void onModbusError(const QString& error);
    void onModbusSuccess();

private:
    // UI组件
    void setupUI();
    void updateUI();

    // 测试流程控制
    void startTestSequence();
    void stopTestSequence();
    void resetTestSequence();
    void executeStep(int stepIndex);

    // 具体测试步骤实现
    void step1_SetSpikeRecovery();              // 设置加标回收模式
    void step2_SetDynamicSpike();               // 设置动态加标
    void step3_StartProcess();                  // 启动流程
    void step4_WaitReady1();                    // 等待第一次准备完成
    void step5_StartAnalysis1();                // 开始第一次分析
    void step6_WriteConcentrationAndFinish1();  // 写入第一次浓度值并完成分析
    void step7_WaitReady2();                    // 等待第二次准备完成
    void step8_StartAnalysis2();                // 开始第二次分析
    void step9_WriteConcentrationAndFinish2();  // 写入第二次浓度值并完成分析
    void step10_ReadRecoveryRate();             // 读取加标回收率
    void step11_TestComplete();                 // 测试完成

    // 辅助函数
    void logMessage(const QString& message);
    void setStepStatus(int stepIndex, const QString& status);
    void pollReadyStatus();

private:
    // Modbus连接
    ModbusHelper* m_modbusHelper;
    bool m_connected;

    // 测试流程控制
    int m_currentStep;
    bool m_testRunning;
    QTimer* m_stepTimer;
    QTimer* m_pollTimer;

    // 测试数据
    float m_concentration1;  // 第一次浓度值
    float m_concentration2;  // 第二次浓度值
    float m_recoveryRate;    // 加标回收率
    int m_stepDelay;         // 步骤间延迟时间(毫秒)

    // UI组件
    QGroupBox* m_connectionGroup;
    QGroupBox* m_testControlGroup;
    QGroupBox* m_testDataGroup;
    QGroupBox* m_logGroup;

    // 连接控件
    QPushButton* m_connectBtn;
    QPushButton* m_disconnectBtn;
    QSpinBox* m_portSpinBox;
    QLabel* m_connectionStatus;

    // 测试控制
    QPushButton* m_startTestBtn;
    QPushButton* m_stopTestBtn;
    QPushButton* m_resetBtn;
    QProgressBar* m_progressBar;
    QLabel* m_currentStepLabel;

    // 测试数据输入
    QDoubleSpinBox* m_concentration1SpinBox;
    QDoubleSpinBox* m_concentration2SpinBox;
    QLabel* m_recoveryRateLabel;

    // 步骤延迟控制
    QSpinBox* m_stepDelaySpinBox;
    QLabel* m_stepDelayLabel;

    // 日志显示
    QTextEdit* m_logTextEdit;

    // 步骤标签数组
    QVector<QLabel*> m_stepLabels;

    // 常量定义
    static const int TOTAL_STEPS = 11;
    static const int STEP_TIMEOUT = 30 * 60 * 1000;  // 步骤超时
    static const int POLL_INTERVAL = 1000;           // 1秒轮询间隔

    // Modbus寄存器地址
    static const int REG_SPIKE_MODE = 0x006F;          // 加标模式
    static const int REG_DYNAMIC_SPIKE = 0x0064;       // 动态加标选择
    static const int REG_START_PROCESS = 0x0099;       // 启动流程
    static const int REG_CONCENTRATION_LOW = 0x0300;   // 浓度值低位
    static const int REG_CONCENTRATION_HIGH = 0x0301;  // 浓度值高位
    static const int REG_ANALYSIS_CONTROL = 0x0302;    // 分析控制
    static const int REG_READY_STATUS = 0x0303;        // 准备状态
    static const int REG_RECOVERY_LOW = 0x0305;        // 回收率低位
    static const int REG_RECOVERY_HIGH = 0x0306;       // 回收率高位
};

#endif  // SPIKE_RECOVERY_TEST_DEMO_H